package com.neusoft.neuiotms.dcom.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.web.dto.result.PageResultDTO;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.dto.result.ResultListDTO;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.dcom.dto.WorkDailyDTO;
import com.neusoft.neuiotms.dcom.service.WorkDailyService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Api(tags = "日报")
@RestController
@Slf4j
@RequestMapping(value = "/api/w/workDaily")
public class WorkDailyController {

    @Autowired
    private WorkDailyService workDailyService;

    @ApiOperation("查询所有日报")
    @GetMapping
    public ResultListDTO<WorkDailyDTO> index(final Searchable searchable, final UserBean userBean) {
        final List<WorkDailyDTO> DTOs = this.workDailyService.index(searchable, userBean);
        final ResultListDTO<WorkDailyDTO> result = ResultListDTO.success(DTOs);
        return result;
    }

    @ApiOperation("分页查询所有日报")
    @GetMapping("/p")
    public PageResultDTO<WorkDailyDTO> search(final Pageable pageable, final Searchable searchable,
            final UserBean userBean) {
        return PageResultDTO.success(this.workDailyService.search(pageable, searchable, userBean));
    }

    @ApiOperation("创建日报")
    @PostMapping("")
    public ResultDTO<WorkDailyDTO> create(@RequestBody final WorkDailyDTO dto, final UserBean user) {
        final WorkDailyDTO result = this.workDailyService.create(dto);
        return ResultDTO.success(result);
    }

    @ApiOperation(value = "修改日报")
    @RequestMapping(path = "/{id}", method = {RequestMethod.PUT, RequestMethod.POST })
    public ResultDTO<WorkDailyDTO> update(@PathVariable final Long id,
            @RequestBody final WorkDailyDTO dto, final UserBean user) {

        if (user != null) {
            dto.setIncidentUserCode(user.getUsername());
            dto.setIncidentUserName(user.getName());
        }

        final WorkDailyDTO result = this.workDailyService.update(id, dto);
        return ResultDTO.success(result);
    }

    @ApiOperation("日报详情")
    @GetMapping("/{id}")
    public ResultDTO<WorkDailyDTO> details(@PathVariable final Long id) {
        final WorkDailyDTO dto = this.workDailyService.details(id);
        return ResultDTO.success(dto);
    }

    @ApiOperation("删除日报")
    @DeleteMapping("/{id}")
    public ResultDTO<Void> delete(@PathVariable final Long id) {
        this.workDailyService.delete(id);
        return ResultDTO.success();
    }

    @ApiOperation("导出日报")
    @GetMapping(value = "/export")
    public void download(final Searchable searchable, final Pageable pageable,
            final HttpServletResponse response, final UserBean userBean) {

        final Workbook workbook = this.workDailyService.export(searchable, userBean);
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=%s",
                            URLEncoder.encode("日报导出" + LocalDateTime.now() + ".xlsx", "UTF-8")));
            workbook.write(out);
            out.flush();
        } catch (final Exception e) {
            WorkDailyController.log.error("日报导出失败", e);
        } finally {
            try {
                out.close();
            } catch (final IOException e) {
                WorkDailyController.log.error("日报导出关闭流失败", e);
            }
        }
    }

    @ApiOperation("日报统计")
    @GetMapping("/stats")
    public ResultDTO<?> todayStats() {
        final Map<String, Long> result = this.workDailyService.reportStats(new Date());
        return ResultDTO.success(result);
    }

    @ApiOperation("下载导入模版")
    @GetMapping("/template")
    public void downloadTpl(final HttpServletResponse response, final UserBean user) {

        final Workbook workbook = this.workDailyService.template(user);
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=%s",
                            URLEncoder.encode(workbook.getSheetName(0) + ".xlsx", "UTF-8")));
            workbook.write(out);
            out.flush();
        } catch (final Exception e) {
            WorkDailyController.log.error("", e);
        } finally {
            try {
                out.close();
            } catch (final IOException e) {
                WorkDailyController.log.error("", e);
            }
        }
    }

    @ApiOperation("导入")
    @PostMapping("/import")
    public ResultDTO<?> importTpl(@RequestParam("file") final MultipartFile file, final UserBean user) {
        try {
            this.workDailyService.importExcel(file.getInputStream(), user);
        } catch (final IOException e) {
            e.printStackTrace();
            throw new UnitedException(e.getMessage());
        }
        return ResultDTO.success();
    }

    @ApiOperation("日报统计报表")
    @GetMapping("/stats/report")
    public PageResultDTO<Map<String, Object>> reportStats(final Pageable pageable,
            @RequestParam(required = false) final String username,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") final Date start,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") final Date end) {
        final Page<Map<String, Object>> result = this.workDailyService.report(pageable, username, start, end);
        return PageResultDTO.success(result);
    }

    @ApiOperation("导出日报统计")
    @GetMapping(value = "/stats/export")
    public void exportStats(@RequestParam(required = false) final String username,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") final Date start,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") final Date end,
            final HttpServletResponse response) {

        final Workbook workbook = this.workDailyService.exportReport(username, start, end);
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=%s",
                            URLEncoder.encode("日报统计导出" + LocalDateTime.now() + ".xlsx", "UTF-8")));
            workbook.write(out);
            out.flush();
        } catch (final Exception e) {
            WorkDailyController.log.error("日报统计导出失败", e);
        } finally {
            try {
                out.close();
            } catch (final IOException e) {
                WorkDailyController.log.error("日报统计导出关闭流失败", e);
            }
        }
    }

    @ApiOperation("服务总时长")
    @GetMapping("/service/time/total")
    public ResultDTO<Long> serviceTimeTotal(final UserBean user) {
        final long total = this.workDailyService.serviceTimeTotal(user);
        return ResultDTO.success(total);
    }

    @ApiOperation("日报提醒测试")
    @GetMapping("/notice/test")
    public ResultDTO<?> noticeTest() {
        this.workDailyService.checkDailyReportNotice();
        return ResultDTO.success();
    }

    @ApiOperation("获取一线工程师半年或一年日志服务统计")
    @GetMapping("/service/summary/{year}/{type}")
    public ResultListDTO<Map<String, Object>> getServiceSummaryOfWorker(@PathVariable final int year,
            @PathVariable final String type, final UserBean user) {
        final List<Map<String, Object>> result = this.workDailyService.getServiceSummaryOfWorker(year, type, user);
        return ResultListDTO.success(result);
    }

}
